Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.11.2018, 09:12
Аспирант
Отправить личное сообщение для Svorg Посмотреть профиль Найти все сообщения от Svorg
 
Регистрация: 16.11.2018
Сообщений: 38

Можно ли вызывать асинхронный XMLHttpRequest якобы синхронно? Или Promise потянут?
Доброе утро!
Допустим мне надо такое:
  1. Объявить пустой массив.
  2. Вызвать асинхронный XMLHttpRequest.
  3. Дождаться его выполнения и проанализировать response.
  4. Выполнить цикл, количество итераций которого становится понятным лишь на предыдущем шаге.
  5. В теле цикла мне надо:
    1. Сделать паузу в 500мс.
    2. Создать и заполнить FormData (для его заполнения может потребоваться дополнительный XMLHttpRequest, результат которого соответственно надо также дождаться).
    3. Выполнить асинхронный XMLHttpRequest с текущим FormData.
    4. Дождаться его выполнения и проанализировать response.
    5. Если response чем-то мне не понравился - надо опять сделать паузу в 500мс и повторить этот же запрос (и повторять до тех пор, пока не станет нормальным).
    6. Если response нормальный - то сложить его в массив.
  6. После окончания цикла надо обработать массив со всеми результатами.
  7. Возможно потребуется вложенный цикл, но это пока не точно.
Явно вызывать XMLHttpRequest синхронно (третий параметр open) - невозможно, оно стреляет всякие ошибки, да и пишут мол устарело. Какую-то может обёртку можно придумать?
Читал про Promise, но как с ними сгородить подобное? И как бы ничё что цикл может быть с сотнями итераций, возможно тысячами, не залипнет ли нахрен..?

Основной целевой браузер Chrome. Никакие библиотеки не используются, никаких jQuery и прочего.
Кто-то может посоветовать что-то? Спасибо!
Ответить с цитированием
  #2 (permalink)  
Старый 16.11.2018, 10:03
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 641

схематично как-то так:
index.html
<script>
  const Process = function () {
    var count = 1
    var bs = []
    return {
      req1: async () => {
        var a = await fetch('http://localhost:2999/get1.php')
        var a_r = await a.text()
        if (parseInt(a_r) === 1) {
          var intervalId = setInterval(async () => {
            count++
            var b = await fetch('http://localhost:2999/get2.php')
            var b_r = await b.text()
            bs.push(b_r)
            if (count > 5) {
              console.log(count, bs)
              clearInterval(intervalId)
            }
          }, 500)
        }
      }
    }
  }

  const instance = new Process();
  instance.req1()

</script>


get1.php
<?php
echo '1';


get2.php
<?php
echo '2';
Ответить с цитированием
  #3 (permalink)  
Старый 16.11.2018, 13:50
Аспирант
Отправить личное сообщение для Svorg Посмотреть профиль Найти все сообщения от Svorg
 
Регистрация: 16.11.2018
Сообщений: 38

оу... Нечто реально любопытное, спасибо.
А под капотом этих async/await/fetch точно те же Promise?
Ответить с цитированием
  #4 (permalink)  
Старый 16.11.2018, 14:12
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 641

Странный ты какой-то Билли, что с тобой? ) У меня скитлстрянка
https://tc39.github.io/ecmascript-as...it/#desugaring

https://github.com/github/fetch/blob/master/fetch.js
Ответить с цитированием
  #5 (permalink)  
Старый 19.11.2018, 13:13
Аспирант
Отправить личное сообщение для Svorg Посмотреть профиль Найти все сообщения от Svorg
 
Регистрация: 16.11.2018
Сообщений: 38

Походу fetch() не позволяет получать responseType в виде document... Хренова...
Попробую что ли переобернуть XMLHttpRequest как свой fetchEx()...
Ответить с цитированием
  #6 (permalink)  
Старый 19.11.2018, 13:46
Аспирант
Отправить личное сообщение для Svorg Посмотреть профиль Найти все сообщения от Svorg
 
Регистрация: 16.11.2018
Сообщений: 38

Или как-то так...
const fetchDoc=async(a,b)=>{return new DOMParser().parseFromString(await(await fetch(a,b)).text(),'text/html')};
Ответить с цитированием
  #7 (permalink)  
Старый 19.11.2018, 14:23
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Или цикл можно оставить циклом

набросок кода
function delay(ms) {
	return new Promise(resolve => setTimeout(resolve, ms));
}

async function process() {
	const responses = [];

	const response = await fetch("/1")
	const count = Number(await response.text());
	let index = 0;

	while(index++ < count) {
		await delay(500);

		const response = await fetch("/data-for-form-data");
		const formData = new FormData();

		const request = new Request("/send-form-data", {
			body: formData,
			method: "post"
		});

		// функция для проверки ответа
		const isOk = async response => {
			// например, тело ответа должно быть больше 100 символов
			return (await response.text()) > 100;
		};

		var sendedFormResponse;

		while(true) {
			sendedFormResponse = await fetch(request);

			if(isOk(sendedFormResponse))
				break;
			else
				await delay(500)
		}

		array.push(sendedFormResponse);
	}

	for(const response of responses) {
		// обработать массив со всеми результатами.
	}

	return responses;
}

process();

// тут конечно могут быть параметры и эта функция
// может ожидаться в другом асинхронном коде и т. д.

Последний раз редактировалось Malleys, 19.11.2018 в 14:37.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск